package com.guocloud.medimind.controller;

import com.guocloud.medimind.dto.ProcessTextRequest;
import com.guocloud.medimind.dto.TemplateMatchRequest;
import com.guocloud.medimind.dto.GenerateRecordRequest;
import com.guocloud.medimind.service.TemplateProcessService;
import com.guocloud.medimind.utils.TextEncodingConverter;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/api/template")
@Tag(name = "病历模板处理", description = "提供病历模板提取、匹配与生成功能")
public class TemplateController {

    @Autowired
    private TemplateProcessService templateProcessService;
    
    @Autowired
    private TextEncodingConverter textEncodingConverter;

    @PostMapping("/process/text")
    @Operation(summary = "一站式处理文本病历", description = "将文本内容通过一系列步骤转换为结构化JSON")
    public Map<String, Object> processTextWithRequest(@RequestBody ProcessTextRequest request) {
        String textContent = request.getTextContent();
        
        // 检测并修复可能的编码问题
        textContent = textEncodingConverter.fixEncoding(textContent);
        
        // 步骤1: 提取键结构
        Map<String, Object> keysOnly = templateProcessService.extractKeysFromText(textContent);
        
        // 步骤2: 根据键结构匹配模板
        Map<String, Object> matchedTemplate = templateProcessService.matchTemplate(keysOnly);
        
        // 步骤3: 生成完整病历JSON
        return templateProcessService.generateFullRecord(textContent, matchedTemplate);
    }
    
    @PostMapping(value = "/process/raw", consumes = MediaType.TEXT_PLAIN_VALUE)
    @Operation(summary = "一站式处理原始文本病历", description = "将原始文本内容通过一系列步骤转换为结构化JSON")
    public Map<String, Object> processRawText(@RequestBody String rawText) {
        // 检测并修复可能的编码问题
        rawText = textEncodingConverter.fixEncoding(rawText);
        
        // 步骤1: 提取键结构
        Map<String, Object> keysOnly = templateProcessService.extractKeysFromText(rawText);
        
        // 步骤2: 根据键结构匹配模板
        Map<String, Object> matchedTemplate = templateProcessService.matchTemplate(keysOnly);
        
        // 步骤3: 生成完整病历JSON
        return templateProcessService.generateFullRecord(rawText, matchedTemplate);
    }
    
    @PostMapping("/process/file")
    @Operation(summary = "一站式处理病历文件", description = "将上传的文件内容通过一系列步骤转换为结构化JSON")
    public Map<String, Object> processFile(@RequestParam("file") MultipartFile file) throws IOException {
        // 先尝试用UTF-8读取
        String textContent = new String(file.getBytes(), StandardCharsets.UTF_8);
        
        // 检测并修复可能的编码问题
        textContent = textEncodingConverter.fixEncoding(textContent);
        
        // 如果依然存在乱码，可能需要尝试不同编码
        if (textContent.contains("") || textContent.contains("□")) {
            try {
                // 尝试使用GBK编码重新读取
                textContent = new String(file.getBytes(), "GBK");
            } catch (Exception e) {
                // 忽略异常，继续使用之前的结果
            }
        }
        
        // 使用一站式处理方法直接生成结构化病历记录（只调用一次大模型）
        return templateProcessService.processSingleStep(textContent);
    }
    
    @PostMapping("/process/plaintext")
    @Operation(summary = "一站式处理病历文本", description = "将文本内容直接转换为结构化JSON")
    public Map<String, Object> processText(@RequestBody String textContent) {
        // 检测并修复可能的编码问题
        textContent = textEncodingConverter.fixEncoding(textContent);
        
        // 使用一站式处理方法直接生成结构化病历记录（只调用一次大模型）
        return templateProcessService.processSingleStep(textContent);
    }
    
    @PostMapping("/extract/keys/text")
    @Operation(summary = "步骤1: 从文本提取键结构", description = "使用大模型从文本中提取病历的键结构")
    public Map<String, Object> extractKeysFromText(@RequestBody String textContent) {
        // 检测并修复可能的编码问题
        textContent = textEncodingConverter.fixEncoding(textContent);
        return templateProcessService.extractKeysFromText(textContent);
    }
    
    @PostMapping("/extract/keys/file")
    @Operation(summary = "步骤1: 从文件提取键结构", description = "使用大模型从文件中提取病历的键结构")
    public Map<String, Object> extractKeysFromFile(@RequestParam("file") MultipartFile file) throws IOException {
        // 使用专门的编码处理器读取文件
        String textContent;
        try {
            textContent = new String(file.getBytes(), StandardCharsets.UTF_8);
            textContent = textEncodingConverter.fixEncoding(textContent);
            
            // 如果还有乱码，尝试其他编码
            if (textContent.contains("") || textContent.contains("□")) {
                // 尝试GBK编码
                textContent = new String(file.getBytes(), "GBK");
            }
        } catch (Exception e) {
            // 如果所有尝试都失败，返回错误信息
            Map<String, Object> errorResult = new HashMap<>();
            errorResult.put("error", "文件编码解析失败，请检查文件编码格式");
            errorResult.put("message", e.getMessage());
            return errorResult;
        }
        
        return templateProcessService.extractKeysFromText(textContent);
    }
    
    @PostMapping("/match")
    @Operation(summary = "步骤2: 匹配模板", description = "根据提取的键结构匹配相应的病历模板")
    public Map<String, Object> matchTemplate(@RequestBody TemplateMatchRequest request) {
        return templateProcessService.matchTemplate(request.getKeysJson());
    }
    
    @PostMapping("/generate")
    @Operation(summary = "步骤3: 生成完整记录", description = "根据原始文本和匹配的模板生成完整的结构化病历")
    public Map<String, Object> generateFullRecord(@RequestBody GenerateRecordRequest request) {
        // 检测并修复可能的编码问题
        String originalText = textEncodingConverter.fixEncoding(request.getOriginalText());
        return templateProcessService.generateFullRecord(originalText, request.getMatchedTemplate());
    }
    
    @PostMapping("/detect-encoding")
    @Operation(summary = "检测文本编码", description = "检测并修复文本的编码问题")
    public Map<String, Object> detectEncoding(@RequestBody String text) {
        Map<String, Object> result = new HashMap<>();
        
        // 保存原始文本信息
        result.put("originalLength", text.length());
        result.put("originalSample", text.length() > 100 ? text.substring(0, 100) + "..." : text);
        
        // 检测并修复编码
        String fixedText = textEncodingConverter.fixEncoding(text);
        
        // 保存修复后的文本信息
        result.put("fixedLength", fixedText.length());
        result.put("fixedSample", fixedText.length() > 100 ? fixedText.substring(0, 100) + "..." : fixedText);
        result.put("isFixed", !fixedText.equals(text));
        
        return result;
    }
} 